package ua.kharkov.khpi.tarasenko.bach.web.command.any;

import java.sql.Connection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import ua.kharkov.khpi.tarasenko.bach.core.Constant;
import ua.kharkov.khpi.tarasenko.bach.core.LocalizedResourceManager;
import ua.kharkov.khpi.tarasenko.bach.core.EShopException;
import ua.kharkov.khpi.tarasenko.bach.core.db.ConnectionManager;
import ua.kharkov.khpi.tarasenko.bach.core.db.DBUtils;
import ua.kharkov.khpi.tarasenko.bach.core.user.PasswordEncryptor;
import ua.kharkov.khpi.tarasenko.bach.core.user.Role;
import ua.kharkov.khpi.tarasenko.bach.core.user.UserBean;
import ua.kharkov.khpi.tarasenko.bach.dao.core.DAOFactory;
import ua.kharkov.khpi.tarasenko.bach.dao.core.user.UserDAO;
import ua.kharkov.khpi.tarasenko.bach.dao.core.user.UserDTO;
import ua.kharkov.khpi.tarasenko.bach.web.command.Command;

/**
 * Command to authenticate user in application.
 * 
 * @author oleksandr
 * 
 */
public class AuthenticationCommand extends Command {
	private static final Logger log = Logger
			.getLogger(AuthenticationCommand.class);

	private static final String PARAMETER_EMAIL = "email";
	private static final String PARAMETER_PASSWORD = "password";

	@Override
	public String execute(HttpServletRequest request,
			HttpServletResponse response) throws EShopException {

		String email = request.getParameter(PARAMETER_EMAIL);
		if (log.isTraceEnabled()) {
			log.trace("Got parameter from request " + PARAMETER_EMAIL + "="
					+ email);
		}

		String password = request.getParameter(PARAMETER_PASSWORD);
		if (log.isTraceEnabled()) {
			log.trace("Got parameter from request " + PARAMETER_PASSWORD + "="
					+ password);
		}

		// Create LocalizedResourceManager to get localized error messages
		LocalizedResourceManager LRManager = getLocalizedResourceManager(request);

		String errorMessage = null;
		String forward = Constant.PAGE_AUTHENTICATION_RESULT;

		boolean isEmailAndPassValid = false;
		if ((email == null) || (password == null) || (email.isEmpty())
				|| (password.isEmpty())) {
			
			errorMessage = LRManager
					.getMessage("error_message.empty_email_password");
		} else {

			Connection conn = null;

			try {

				// Get connection to DB and looking for user by email
				conn = ConnectionManager.getConnection();
				UserDAO userDAO = DAOFactory.getDAOFactory(
						DAOFactory.DAO_TYPE.MYSQL).getUserDAO(conn);
				UserDTO userDTO = userDAO.findUserByEmail(email);

				// Code password that we got from request(user)
				PasswordEncryptor cryptor = new PasswordEncryptor();
				String cryptedPassword = cryptor.encode(password);

				if ((userDTO == null)
						|| (!cryptedPassword.equals(userDTO.getPassword()))) {

					errorMessage = LRManager
							.getMessage("error_message.no_such_user");
				} else {

					isEmailAndPassValid = true;

					UserBean userBean = createUserBean(userDTO);
					HttpSession session = request.getSession();

					// Put user bean into his session
					session.setAttribute(Constant.ATTRIBUTE_USER_BEAN, userBean);
					if (log.isTraceEnabled()) {
						log.trace("Set session attribute "
								+ Constant.ATTRIBUTE_USER_BEAN + " = "
								+ userBean);
					}

					// Check what role user has and set appropriate url to
					// redirect
					String redirectUrl = "";
					if (userBean.getUserRole() == Role.ADMIN) {
						redirectUrl = Constant.COMMAND_SHOW_USERS_LIST;
					} else {
						redirectUrl = Constant.COMMAND_SHOW_ITEMS_LIST;
					}

					request.setAttribute(Constant.ATTRIBUTE_REDIRECT_URL,
							redirectUrl);
					if (log.isTraceEnabled()) {
						log.trace("Set request attribute "
								+ Constant.ATTRIBUTE_REDIRECT_URL + " = "
								+ redirectUrl);
					}

					// Say that email and pass are valid and there are not any
					// errors
					request.setAttribute(Constant.ATTRIBUTE_IS_VALID,
							isEmailAndPassValid);
					if (log.isTraceEnabled()) {
						log.trace("Set request attribute "
								+ Constant.ATTRIBUTE_IS_VALID + " = "
								+ isEmailAndPassValid);
					}

					log.info("User with id " + userDTO.getId() + " logged as "
							+ userBean.getUserRole());
				}
			} catch (EShopException e) {
				DBUtils.close(conn);
				throw e;
			} finally {
				if (conn != null) {
					DBUtils.close(conn);
				}
			}
		}

		if (errorMessage != null) {
			forward = processError(request, errorMessage);
		}

		if (log.isDebugEnabled()) {
			log.debug("Forward to " + forward);
		}
		return forward;
	}

	/**
	 * Creates UserBean instance from UserDTO.
	 * 
	 * @param userDTO
	 *            .
	 * @return userBean.
	 */
	private static UserBean createUserBean(UserDTO userDTO) {
		UserBean userBean = new UserBean();
		userBean.setUserId(userDTO.getId());
		userBean.setUserFirstName(userDTO.getFirstName());
		Role userRole = userDTO.getRole();
		userBean.setUserRole(userRole);
		return userBean;
	}

	@Override
	protected String processError(HttpServletRequest request,
			String errorMessage) {
		boolean isEmailAndPassValid = false;
		String forward = Constant.PAGE_AUTHENTICATION_RESULT;

		request.setAttribute(Constant.ATTRIBUTE_ERROR_MESSAGE, errorMessage);
		if (log.isTraceEnabled()) {
			log.trace("Set request attribute "
					+ Constant.ATTRIBUTE_ERROR_MESSAGE + "=" + errorMessage);
		}

		request.setAttribute(Constant.ATTRIBUTE_IS_VALID, isEmailAndPassValid);
		if (log.isTraceEnabled()) {
			log.trace("Set request attribute " + Constant.ATTRIBUTE_IS_VALID
					+ "=" + isEmailAndPassValid);
		}
		return forward;
	}
}
